package com.lottery.game.controller.v2.register;

import com.lottery.game.common.Response;
import com.lottery.game.common.constants.GlobalLotteryConstants;
import com.lottery.game.common.exception.BaseException;
import com.lottery.game.common.utils.IPUtils;
import com.lottery.game.constants.RespErrorCodes;
import com.lottery.game.controller.v2.register.request.PhoneCheckRequest;
import com.lottery.game.controller.v2.register.request.SendMessageRequest;
import com.lottery.game.core.model.request.register.RegisterV2Request;
import com.lottery.game.core.model.request.register.VerifyCodeRequest;
import com.lottery.game.core.modules.entity.user.GameUser;
import com.lottery.game.core.modules.service.app.GameUserService;
import com.lottery.game.core.modules.service.app.v2.MessageSendAndCheckService;
import com.lottery.game.core.modules.service.game.LockService;
import com.lottery.game.core.validator.annotation.Validate;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import springfox.documentation.annotations.ApiIgnore;

/**
 * 注册
 *
 * @author chenye
 *
 */
@Slf4j
@RestController
@EnableAutoConfiguration
@RequestMapping(value = "api/v2/register")
@Api(tags = "APP-用户注册相关接口-ok")
public class RegisterV2Controller {

	private static Logger logger = LoggerFactory.getLogger(RegisterV2Controller.class);

	@Autowired
	private LockService lockServiceClient;

	private static String LOCK_REGISTER_KEY = "lock-register-key";

	@Autowired
	private GameUserService gameUserService;

	@Autowired
	private MessageSendAndCheckService messageSendAndCheckService;

	// 发送短信验证码
	@SuppressWarnings("unchecked")
	@ApiOperation(value = "发送手机短信验证码-返回短信验证码token，该字符串需要在检测时传递", notes = "发送短信验证码", httpMethod="POST")
	@PostMapping(value = "/message/send", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	@ResponseBody
	@Validate
	public Response<String> messageSend(@RequestBody SendMessageRequest request) {

		GameUser queryUser = gameUserService.getGameUserByUserName(request.getPhone());
		//如果要注册，手机号已注册，进行提醒
		if (queryUser != null) {
			throw new BaseException(RespErrorCodes.PHONE_EXIST_ERRROR.getErrorMsg());
		}
		return Response.build(messageSendAndCheckService.send(request.getPhone(), "用户注册"));
	}

	/**
	 * 验证验证码是否通过
	 * @param request
	 * @return
	 */
//	@SuppressWarnings("unchecked")
//	@ApiOperation(value = "验证验证码是否通过", notes = "验证验证码是否通过" +
//			"\n    body参数:\n{\n" + "    \"code\": \"5209\",\n" + "    \"phone\": \"15348304229\",\n" + "    \"token\": \"eyJzaWduIjoiNGU2MDE1ZGVmMjY2N2NkOWQyMzgxZGIzZjcyMjRiNDIiLCJ0aW1lc3RhbXAiOiIxNTU1Mjk5MDYyNTE5In0\"\n" + "}", httpMethod="POST")
//	@PostMapping(value = "/validate/code", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
//	@ResponseBody
//	@Validate
//	public Response<Boolean> validateCode(@RequestBody VerifyCodeRequest request) {
//		return Response.build(this.validateCode(request.getPhone(), request.getCode(), request.getToken()));
//	}

	/**
	 * 校验手机验证码
	 */
	private boolean validateCode(String phone, String code, String token) {
		 return messageSendAndCheckService.preCheck(token, code, phone) != null;
	}

	/**
	 * 注册
	 *
	 * @return
	 */
	@ApiOperation(value = "注册", notes = "注册新用户 true 注册成功 false 注册失败", httpMethod="POST")
	@PostMapping(value = "/user", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	@ResponseBody
	@Validate
	public Response<Boolean> register(@RequestBody RegisterV2Request registerRequest, @ApiIgnore HttpServletRequest request) {
		String lockKey = LOCK_REGISTER_KEY + ":" + registerRequest.getPhone();
		//先检验是否可以注册,在上锁
		this.validatePhone(registerRequest.getPhone());
		//判断昵称是否可以注册
		this.validateUserName(registerRequest.getUsername());
		boolean lock = lockServiceClient.lock(lockKey,5);
		if (lock) {
			messageSendAndCheckService.check(registerRequest.getToken(), registerRequest.getCode(), registerRequest.getPhone());
			GameUser gameUser = GameUser.valueOf(registerRequest);
			gameUser.setIp(IPUtils.getRealIps());
			return Response.build(GlobalLotteryConstants.RES_SUCCESS_CODE_ONE,GlobalLotteryConstants.RES_SUCCESS_STR_ONE,
					gameUserService.register(gameUser, registerRequest.getIntroducer()),true);
		} else {
			throw new BaseException("请切勿提交频繁,等候5秒后尝试");
		}
	}


	/**
	  * 校验用户名
	 *
	 * @return
	 */
	@ApiIgnore
	@SuppressWarnings("unchecked")
	@ApiOperation(value = "检查手机号是否被注册", notes = "检查手机号是否被注册，根据手机号判断机器人和用户表, true 可用 false 不可用", httpMethod="POST")
	@PostMapping(value = "/check/phone", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	@ResponseBody
	@Validate
	public Response<Boolean> checkPhone(@RequestBody PhoneCheckRequest request) {
			return Response.build(this.validatePhone(request.getPhone()));
	}

	/**
	 *
	 * @param phone
	 * @return
	 */
	private boolean validatePhone(String phone) {
			if (gameUserService.checkPhone(phone)) {
				return true;
			}
			throw new BaseException("该手机号已注册");
	}
	/**
	 * @Description 判断用户表和机器表是否有重复名字
	 * @param: username
	 * @Return
	 * @Date 2019/4/22_16:05
	 */
	private boolean validateUserName(String username) {
		if (gameUserService.checkUserName(username)) {
			return true;
		}
		throw new BaseException("用户昵称已被注册");
	}
}
